// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Aff_transformation_3.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Aff_transformation_3.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================


// include ====================================================================
#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Aff_transformation_3_doc[] ={
"The class Aff_transformation_3 represents three-dimensioanl affine transformations. \n\
The general form of an affine transformation is based on a homogeneous representation of points. \n\
Thereby all transformations can be realized by matrix multiplications.\n\
For more information see a C++ doc:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Aff_transformation_3.html",

"\
t = Aff_transformation_2( Identity_transformation)\n\
introduces an identity transformation.\n\n\
t = Aff_transformation_2( Translation, Vector_3 v)\n\
introduces a translation by a vector v.\n\n\
t = Aff_transformation_2( Scaling,s,hw = 1)\n\
introduces a scaling by a scale factor s/hw.\n\n\
t = Aff_transformation_2(  m00,m01,m02,m03,m10,m11,m13,m20,m21,m23,hw = 1)\n\
introduces a general affine transformation of the matrix form\n\
|m00 m01 m02 m03|\n\
|m10 m11 m12 m13|\n\
|m20 m21 m22 m23|\n\
|0   0   0   hw |\n\n\
t = Aff_transformation_2( m00,m01,m02,m10,m11,m12,m20,m21,m22,hw = 1)\n\
introduces a general linear transformation of the matrix form",

"t.transform ( Point_3 p) -> Point_3\n\n\
t.transform ( Vector_3 v) -> Vector_3\n\n\
t.transform ( Direction_3 d) -> Direction_3\n\n\
t.transform ( Plane_3 p) -> Plane_3",

"t.inverse () -> Aff_transformation_2\ngives the inverse transformation.",
"t.is_even () -> bool\nreturns true, if the transformation is not reflecting, i.e. \nthe determinant of the involved linear transformation is non-negative.",

"t.is_odd () -> bool\nreturns true, if the transformation is reflecting.",

"t.cartesian (int i,int j) -> m(i,j) of t\n",

"t.homogeneous (int i,int j) -> hm(i,j) of t\n",

"t.m (int i,int j) -> double\nreturns entry mij in a matrix representation in which m33 is 1.",

"t.hm (int i,int j) -> double\nreturns entry mij in some fixed matrix representation.",

"\
t( Point_2 p) -> Point_2\n\n\
t( Vector_2 v) -> Vector_2\n\n\
t( Direction_2 d) -> Direction_2\n\n\
t( Line_2 l) -> Line_2"

};

template <class kernel > 
void Py_Aff_transformation_3()
{

//==========================  Three-dimensional Objects =======================

	typedef typename kernel::Point_3 							Point_3;
	typedef typename kernel::Aff_transformation_3 				Aff_transformation_3;
 	typedef typename kernel::Vector_3 							Vector_3;
 	typedef typename kernel::Direction_3 						Direction_3;
 	typedef typename kernel::Plane_3 							Plane_3;
	typedef typename kernel::FT 								FT;

	using namespace boost::python;

    class_< Aff_transformation_3 >("Aff_transformation_3",Aff_transformation_3_doc[0],init<  >())
        .def(init< const Aff_transformation_3& >(Aff_transformation_3_doc[1]))
        .def(init< const CGAL::Identity_transformation >())
        .def(init< const CGAL::Translation, const Vector_3& >())
        .def(init< const CGAL::Scaling, const FT&, optional< const FT& > >())
		.def(init< const CGAL::Scaling, const double&, optional< const double& > >())
        .def(init< const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, optional< const FT& > >())
        .def(init< const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, optional< const FT& > >())
        .def(init< const double&, const double&, const double&, const double&, const double&, const double&, const double&, const double&, const double&, optional< const double& > >())
        .def(init< const double&, const double&, const double&, const double&, const double&, const double&, const double&, const double&, const double&, const double&, const double&, const double&, optional< const double& > >())

        .def("transform", (Point_3 (Aff_transformation_3::*)(const Point_3&) const)&Aff_transformation_3::transform,Aff_transformation_3_doc[2])
        .def("transform", (Vector_3 (Aff_transformation_3::*)(const Vector_3&) const)&Aff_transformation_3::transform)
        .def("transform", (Direction_3 (Aff_transformation_3::*)(const Direction_3&) const)&Aff_transformation_3::transform)
        .def("transform", (Plane_3 (Aff_transformation_3::*)(const Plane_3&) const)&Aff_transformation_3::transform)
        .def("inverse", &Aff_transformation_3::inverse,Aff_transformation_3_doc[3])
        .def("is_even", &Aff_transformation_3::is_even,Aff_transformation_3_doc[4])
        .def("is_odd", &Aff_transformation_3::is_odd,Aff_transformation_3_doc[5])
        .def("cartesian", &Aff_transformation_3::cartesian,Aff_transformation_3_doc[6])
        .def("homogeneous", &Aff_transformation_3::homogeneous,Aff_transformation_3_doc[7])
        .def("m", &Aff_transformation_3::m,Aff_transformation_3_doc[8])
        .def("hm", &Aff_transformation_3::hm,Aff_transformation_3_doc[9])
        .def("__call__", (Point_3 (Aff_transformation_3::*)(const Point_3&) const)&Aff_transformation_3::operator (),Aff_transformation_3_doc[10])
        .def("__call__", (Vector_3 (Aff_transformation_3::*)(const Vector_3&) const)&Aff_transformation_3::operator ())
        .def("__call__", (Direction_3 (Aff_transformation_3::*)(const Direction_3&) const)&Aff_transformation_3::operator ())
        .def("__call__", (Plane_3 (Aff_transformation_3::*)(const Plane_3&) const)&Aff_transformation_3::operator ())
        .def( self * self )
    ;
}


void export_Aff_transformation_3()
{
	Py_Aff_transformation_3<K>();
}
